﻿#include "cpushbutton.h"
#include <QPainter>
#include <QPainterPath>
#include <QRect>
#include <QStyleOption>
#include <QStylePainter>

CPushButton::CPushButton(QWidget *parent)
    :QWidget(parent),m_bHover(false), m_bPressed(false),
    m_bCheckable(false),m_bChecked(false)
{
    m_BackgroundColor = QColor(236, 236, 236);
    m_PressgroundColor = QColor(204, 228, 247);
    m_HoverColor = QColor(229, 241, 251, 200);
    m_dbRadius = 3;
    m_TextColor = Qt::black;
    m_nAlignment = Left;
    m_iBorderWidth = 1;
    m_BorderColor = Qt::lightGray;
    setTextMargin( 5, 5, 5, 5);
    m_bChangeCursor = true;
    setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed);
    setAttribute(Qt::WA_TranslucentBackground);
    setMouseTracking(true);

}

QSize CPushButton::sizeHint() const
{
    int horMargin = m_marginRight + m_marginLeft;
    int verMargin = m_marginTop + m_marginBottom;
    int w = 0;
    int h = 0;
    if (!getIcon().isNull() || m_bShowIcon) {
        int ih = getIconSize().height();
        int iw = getIconSize().width() + 4;
        w += iw;
        h = qMax(h, ih);
    }

    QString s(getText());
    bool empty = s.isEmpty();
    if (empty)
        s = QStringLiteral("XXXX");
    QFontMetrics fm = fontMetrics();
    QSize sz = fm.size(Qt::TextShowMnemonic, s);
    if(!empty || !w)
        w += sz.width();
    h = qMax(h, sz.height());
    w += horMargin;
    h += verMargin;
    return QSize(w, h);
}

QSize CPushButton::minimumSizeHint() const
{
    return sizeHint();
}

void CPushButton::paintEvent(QPaintEvent* event)
{
    Q_UNUSED(event)
    QPainter painter(this);
    painter.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing);

    QPainterPath path;
    path.addRoundedRect(rect(), m_dbRadius, m_dbRadius);
    QPen pen(m_BorderColor, m_iBorderWidth);
    painter.save();
    painter.setPen(pen);

    if(m_bPressed) {
         painter.fillPath(path, m_PressgroundColor);
    } else if (m_bHover) {
        painter.fillPath(path, m_HoverColor);
    } else {
        painter.fillPath(path, m_BackgroundColor);
    }

    painter.drawPath(path);
    painter.restore();

    //绘制文本
    drawTextOrIcons(&painter);
}

void CPushButton::drawTextOrIcons(QPainter* pPainter)
{

    auto m_iWidth = size().width();
    auto m_iHeight = size().height();
    if(!m_sIcons.isNull())
    {
        auto pixSize = getIconSize();
        // 计算图标的Y
        int iconY = (m_iHeight - getIconSize().height())/2;
        if(m_nAlignment==Left)
        {
            QPixmap pixmap = m_sIcons.pixmap(pixSize,
                                             m_bChecked?QIcon::Selected:QIcon::Normal,
                                             m_bChecked?QIcon::On:QIcon::Off);

            pPainter->drawPixmap(m_marginLeft, iconY, pixmap);
            pPainter->save();
            pPainter->setPen(m_TextColor);
            pPainter->setFont(m_Textfont);
            QTextOption option;
            option.setAlignment(Qt::AlignCenter);
            pPainter->drawText(QRect(m_iWidth*0.5,0,m_iWidth*0.5,m_iHeight), m_sText,option);
            pPainter->restore();
        }
        if(m_nAlignment==Right)
        {

            // 计算Icon的X坐标
            auto iconX = m_iWidth - m_marginRight - pixSize.width();
            QPixmap pixmap = m_sIcons.pixmap(pixSize,
                                             m_bChecked?QIcon::Selected:QIcon::Normal,
                                             m_bChecked?QIcon::On:QIcon::Off);
            pPainter->drawPixmap(iconX, iconY, pixmap);
            pPainter->save();
            pPainter->setPen(m_TextColor);
            pPainter->setFont(m_Textfont);
            QTextOption option;
            option.setAlignment(Qt::AlignCenter);;
            pPainter->drawText(QRect(0,0,m_iWidth*0.5,m_iHeight), m_sText,option);
            pPainter->restore();
        }
    }
    if(m_sIcons.isNull())
    {
        pPainter->save();
        pPainter->setPen(m_TextColor);
        pPainter->setFont(m_Textfont);
        QTextOption option;
        option.setAlignment(Qt::AlignCenter);
        pPainter->drawText(QRect(0, 0, m_iWidth, m_iHeight), m_sText,option);
        pPainter->restore();
    }
}

bool CPushButton::getChangeCursor() const
{
    return m_bChangeCursor;
}

bool CPushButton::getCheckable() const
{
    return m_bCheckable;
}

bool CPushButton::getChecked() const
{
    return m_bChecked;
}

CPushButton &CPushButton::setChangeCursor(bool bChangeCursor)
{
    m_bChangeCursor = bChangeCursor;
    return *this;
}

CPushButton &CPushButton::setCheckable(bool able)
{
    m_bCheckable = able;
    return *this;
}

CPushButton &CPushButton::setChecked(bool checked)
{
    m_bChecked = checked;
    return *this;
}

CPushButton& CPushButton::setShowIcon(bool bShowIcon)
{
    m_bShowIcon = bShowIcon;
    return *this;
}

CPushButton &CPushButton::setTextMargin(int left, int top, int right, int bottom)
{
    m_marginLeft = left;
    m_marginRight = right;
    m_marginTop = top;
    m_marginBottom = bottom;
    return *this;
}

QSize CPushButton::getIconSize() const
{
    if(m_iconSize.isValid())
        return m_iconSize;
    return QSize(24, 24);
}

bool CPushButton::getShowIcon() const
{
    return m_bShowIcon;
}

QColor CPushButton::getBorderColor() const
{
    return m_BorderColor;
}

void CPushButton::mousePressEvent(QMouseEvent *e)
{
    if(e->buttons() & Qt::LeftButton)
    {
        m_bPressed = true;
        emit clicked();
        update();
    }
    if(e->buttons() & Qt::RightButton)
    {
        emit rightclicked();
    }
    QWidget::mousePressEvent(e);
}

void CPushButton::mouseReleaseEvent(QMouseEvent *e)
{
    if(e->button() == Qt::LeftButton) {
        if(m_bCheckable && m_bPressed){
            m_bChecked = !m_bChecked;
            emit checkStateChange(m_bChecked);
        }
        m_bPressed = false;
        update();
    }
    QWidget::mouseReleaseEvent(e);
}

void CPushButton::mouseDoubleClickEvent(QMouseEvent *e)
{
    emit doubleclicked();
    QWidget::mouseDoubleClickEvent(e);
}

void CPushButton::leaveEvent(QEvent *event)
{
    m_bHover = false;
    update();
    unsetCursor();
    QWidget::leaveEvent(event);
}

void CPushButton::enterEvent(QEvent *event)
{
    m_bHover = true;
    update();
    setCursor(Qt::PointingHandCursor);
    QWidget::enterEvent(event);
}

QFont CPushButton::getTextfont() const
{
    return m_Textfont;
}

CPushButton &CPushButton::setTextfont(const QFont &Textfont)
{
    m_Textfont = Textfont;
    return *this;
}

CPushButton& CPushButton::setPressedColor(const QColor &clickedColor)
{
    m_PressgroundColor = clickedColor;
    update();
    return *this;
}

CPushButton &CPushButton::setHoverColor(const QColor &hoverColor)
{
    m_HoverColor = hoverColor;
    update();
    return *this;
}

qreal CPushButton::getRadius() const
{
    return m_dbRadius;
}

CPushButton &CPushButton::setRadius(const qreal &dbRadius)
{
    m_dbRadius = dbRadius;
    return *this;
}

CPushButton &CPushButton::setBorderColor(const QColor& BorderColor)
{
    m_BorderColor = BorderColor;
    return *this;
}

QColor CPushButton::getTextColor() const
{
    return m_TextColor;
}

CPushButton &CPushButton::setTextColor(const QColor &TextColor)
{
    m_TextColor = TextColor;
    update();
    return *this;
}

QString CPushButton::getText() const
{
    return m_sText;
}

CPushButton &CPushButton::setText(const QString &sText)
{
    m_sText = sText;
    return *this;
}

QColor CPushButton::getBackgroundColor() const
{
    return m_BackgroundColor;
}

CPushButton &CPushButton::setBackgroundColor(const QColor &BackgroundColor)
{
    m_BackgroundColor = BackgroundColor;
    update();
    return *this;
}

QIcon CPushButton::getIcon() const
{
    return m_sIcons;
}

CPushButton &CPushButton::setIcon(const QIcon &sIcons,AlignmentFlag alignment)
{
    m_sIcons = sIcons;
    m_nAlignment = alignment;
    update();
    return *this;
}

CPushButton &CPushButton::setIconSize(QSize size)
{
    m_iconSize = size;
    update();
    return *this;
}
